﻿using System;
using NUnit.Framework;
using StoryQ;

namespace SharpRomans.Tests.FigureSpecs
{
	[TestFixture]
	public class ParseTester
	{
		[Test]
		public void ParseString()
		{
			new Story("parse a string")
				.InOrderTo("get a figure instance")
				.AsA("library user")
				.IWant("to be able to parse a string")

				.WithScenario("parse a defined figure")
					.Given(aString_, "I")
					.When(theStringIsParsed)
					.Then(theFigure_Is, RomanFigure.I)

				.WithScenario("parse an undefined figure")
					.Given(aString_, "W")
					.When(theStringIsParsed)
					.Then(throwsArgumentException)

				.WithScenario("parse a multiple character string")
					.Given(aString_, "XI")
					.When(theStringIsParsed)
					.Then(throwsFormatException)

				.WithScenario("figures are unique")
					.Given(aString_, "X")
					.When(theStringIsParsedAgain_, "X")
					.Then(isTheSameFigure)

				.ExecuteWithReport();
		}

		[Test]
		public void ParseChar()
		{
			new Story("parse a char")
				.InOrderTo("get a figure instance")
				.AsA("library user")
				.IWant("to be able to parse a char")

				.WithScenario("parse a defined figure")
					.Given(aCharacter_, 'I')
					.When(theCharIsParsed)
					.Then(theFigure_Is, RomanFigure.I)

				.WithScenario("parse an undefined figure")
					.Given(aCharacter_, 'W')
					.When(theCharIsParsed)
					.Then(throwsArgumentException)

				.WithScenario("figures are unique")
					.Given(aCharacter_, 'X')
					.When(theCharIsParsedAgain_, 'X')
					.Then(isTheSameFigure)

				.ExecuteWithReport();
		}

		[Test]
		public void ParseNumber()
		{
			new Story("parse a number")
				.InOrderTo("get a figure instance")
				.AsA("library user")
				.IWant("to be able to parse a short")

				.WithScenario("parse a defined figure")
					.Given(aNumber_, 1)
					.When(theNumberIsParsed)
					.Then(theFigure_Is, RomanFigure.I)

				.WithScenario("parse an undefined figure")
					.Given(aNumber_, 3)
					.When(theNumberIsParsed)
					.Then(throwsArgumentException)

				.WithScenario("figures are unique")
					.Given(aNumber_, 10)
					.When(theNumberIsParsedAgain_, 10)
					.Then(isTheSameFigure)

				.ExecuteWithReport();
		}

		private void throwsArgumentException()
		{
			TestDelegate cast = () => _figure();
			Assert.That(cast, Throws.ArgumentException);
		}

		private void throwsFormatException()
		{
			TestDelegate cast = () => _figure();
			Assert.That(cast, Throws.InstanceOf<FormatException>());
		}

		string _string;
		private void aString_(string s)
		{
			_string = s;
		}

		char _character;
		private void aCharacter_(char character)
		{
			_character = character;
		}

		short _number;
		private void aNumber_(int number)
		{
			_number = (short)number;
		}

		Func<RomanFigure> _figure;
		private void theStringIsParsed()
		{
			_figure = () => RomanFigure.Parse(_string);
		}

		private RomanFigure _anotherFigure;
		private void theStringIsParsedAgain_(string s)
		{
			_anotherFigure = RomanFigure.Parse(s);
		}

		private void theCharIsParsedAgain_(char c)
		{
			_anotherFigure = RomanFigure.Parse(c);
		}

		private void theNumberIsParsedAgain_(int number)
		{
			_anotherFigure = RomanFigure.Parse((short)number);
		}

		private void theNumberIsParsed()
		{
			_figure = () => RomanFigure.Parse(_number);
		}

		private void theCharIsParsed()
		{
			_figure = () => RomanFigure.Parse(_character);
		}

		private void theFigure_Is(RomanFigure figure)
		{
			Assert.That(_figure(), Is.EqualTo(figure));
		}

		private void isTheSameFigure()
		{
			Assert.That(_figure(), Is.SameAs(_anotherFigure));
		}


	}

	[TestFixture]
	public class TryParseTester
	{
		[Test]
		public void TryParseChar()
		{
			new Story("try parse a char")
				.InOrderTo("try to get a figure instance")
				.AsA("library user")
				.IWant("to be able to try to parse a char")

				.WithScenario("parse a defined figure")
					.Given(aCharacter_, 'I')
					.When(theCharIsParsed)
					.Then(theResultIs_, true)
					.And(theFigure_Is, RomanFigure.I)

				.WithScenario("parse an undefined figure")
					.Given(aCharacter_, 'W')
					.When(theCharIsParsed)
					.Then(theResultIs_, false)
					.And(theFigure_Is, (RomanFigure)null)

				.WithScenario("figures are unique")
					.Given(aCharacter_, 'X')
					.When(theCharIsParsed)
					.And(theCharIsParsedAgain_, 'X')
					.Then(isTheSameFigure)

				.ExecuteWithReport();
		}

		private void theResultIs_(bool obj)
		{
			Assert.That(_result, Is.EqualTo(obj));
		}

		char _character;
		private void aCharacter_(char character)
		{
			_character = character;
		}

		private RomanFigure _anotherFigure;
		private bool _result;
		private void theCharIsParsedAgain_(char c)
		{
			_result = RomanFigure.TryParse(c, out _anotherFigure);
		}

		private RomanFigure _parsed;
		private void theCharIsParsed()
		{
			_result = RomanFigure.TryParse(_character, out _parsed);
		}

		private void theFigure_Is(RomanFigure figure)
		{
			Assert.That(_parsed, Is.EqualTo(figure));
		}

		private void isTheSameFigure()
		{
			Assert.That(_parsed, Is.SameAs(_anotherFigure));
		}
	}

	[TestFixture]
	public class NameTester
	{
		[Test]
		public void RomanFiguresNames()
		{
			new Story("names")
				.InOrderTo("get the latin names of individual figures")
				.AsA("library user")
				.IWant("to be able to invoke a method on a roman figure")

						.WithScenario("zero")
							.Given(theFigure_DoesHaveAName, RomanFigure.N)
							.When(theNameIsObtained)
							.Then(theNameIsNotEmpty)

						.WithScenario("one")
							.Given(theFigure_DoesHaveAName, RomanFigure.I)
							.When(theNameIsObtained)
							.Then(theNameIsNotEmpty)

						.WithScenario("five")
							.Given(theFigure_DoesHaveAName, RomanFigure.V)
							.When(theNameIsObtained)
							.Then(theNameIsNotEmpty)

						.WithScenario("ten")
							.Given(theFigure_DoesHaveAName, RomanFigure.X)
							.When(theNameIsObtained)
							.Then(theNameIsNotEmpty)

						.WithScenario("figures with names")
							.Given(theFigure_DoesHaveAName, RomanFigure.L)
							.When(theNameIsObtained)
							.Then(theNameIsNotEmpty)

						.WithScenario("figures with names")
							.Given(theFigure_DoesHaveAName, RomanFigure.C)
							.When(theNameIsObtained)
							.Then(theNameIsNotEmpty)

						.WithScenario("figures with names")
							.Given(theFigure_DoesHaveAName, RomanFigure.D)
							.When(theNameIsObtained)
							.Then(theNameIsNotEmpty)

						.WithScenario("figures with names")
							.Given(theFigure_DoesHaveAName, RomanFigure.M)
							.When(theNameIsObtained)
							.Then(theNameIsNotEmpty)
				.ExecuteWithReport();
		}

		RomanFigure _subject;
		string _name;
		private void theNameIsObtained()
		{
			_name = _subject.Description;
		}

		private void theFigure_DoesHaveAName(RomanFigure figureWithName)
		{
			_subject = figureWithName;
		}

		private void theNameIsNotEmpty()
		{
			Assert.That(_name, Is.Not.Empty);
		}
	}

	[TestFixture]
	public class ValueTester
	{
		[Test]
		public void RomanFiguresValues()
		{
			new Story("values")
				.InOrderTo("get the integral values of individual figures")
				.AsA("library user")
				.IWant("to be able to invoke a method on a roman figure")

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.I)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 1u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.V)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 5u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.X)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 10u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.L)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 50u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.C)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 100u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.D)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 500u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.M)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 1000u)

				.ExecuteWithReport();
		}

		RomanFigure _subject;
		private void aRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		short _value;
		private void theValueIsObtained()
		{
			_value = _subject.Value;
		}

		private void theValue_IsCorrect(uint value)
		{
			Assert.That(_value, Is.EqualTo(value));
		}
	}

	[TestFixture]
	public class ToCharTester
	{
		[Test]
		public void RomanFigureCharacters()
		{
			new Story("characters")
				.InOrderTo("get the character of individual figures")
				.AsA("library user")
				.IWant("to be able to invoke a method on a roman figure")

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.I)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'I')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.V)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'V')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.X)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'X')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.L)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'L')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.C)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'C')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.D)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'D')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.M)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'M')

				.ExecuteWithReport();
		}

		RomanFigure _subject;
		private void aRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		char _character;
		private void theCharacterIsObtained()
		{
			_character = _subject.Figure;
		}

		private void theCharacter_Is(char character)
		{
			Assert.That(_character, Is.EqualTo(character));
		}
	}

	[TestFixture]
	public class RoleTester
	{
		[Test]
		public void RomanFigureRoles()
		{
			new Story("roles")
				.InOrderTo("know whether a figure is substractive or not")
				.AsA("library user")
				.IWant("to be able to invoke a method on a roman figure")

				.WithScenario("substractive figure")
					.Given(aSubstractiveRomanFigure_, RomanFigure.I)
					.When(substractivenessIsChecked)
					.Then(substractivenessIs_, true)
					.And(isNotSingle)

				.WithScenario("non-substractive figure")
					.Given(aNonSubstractiveRomanFigure_, RomanFigure.V)
					.When(substractivenessIsChecked)
					.Then(substractivenessIs_, false)
					.And(isSingle)

				.ExecuteWithReport();

			Assert.Inconclusive("more test remaining: repeteable");
		}

		RomanFigure _subject;
		private void aSubstractiveRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		private void aNonSubstractiveRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		bool _substractiveness;
		private void substractivenessIsChecked()
		{
			_substractiveness = _subject.IsSubstractive;
		}

		private void substractivenessIs_(bool substractiveness)
		{
			Assert.That(_substractiveness, Is.EqualTo(substractiveness));
		}

		private void isSingle()
		{
			Assert.That(_subject.IsSingle, Is.True);
		}

		private void isNotSingle()
		{
			Assert.That(_subject.IsSingle, Is.False);
		}
	}

	[TestFixture]
	public class RomanFigureComparisonTester
	{
		[Test]
		public void CompareToRomanFigure()
		{
			new Story("compare to roman figure")
				.InOrderTo("say that a figure is greater or lower than another figure")
				.AsA("library user")
				.IWant("compare a roman figure against another roman figure")

			.WithScenario("one figure is greater than another")
				.Given(TheRomanfigure_, RomanFigure.V)
				.When(IsComparedTo_, RomanFigure.I)
				.Then(IsGreaterThanZero)

			.WithScenario("one figure is less than another")
				.Given(TheRomanfigure_, RomanFigure.I)
				.When(IsComparedTo_, RomanFigure.X)
				.Then(IsLessThanZero)

			.WithScenario("one figure is equal to another")
				.Given(TheRomanfigure_, RomanFigure.X)
				.When(IsComparedTo_, RomanFigure.X)
				.Then(IsZero)

			.WithScenario("one figure is compared to NULL")
				.Given(TheRomanfigure_, RomanFigure.X)
				.When(IsComparedTo_, (RomanFigure)null)
				.Then(IsGreaterThanZero)

			.ExecuteWithReport();
		}

		[Test]
		public void GreaterThanRomanFigure()
		{
			new Story("greater than roman figure")
				.InOrderTo("say that a figure is greater than another figure")
				.AsA("library user")
				.IWant("apply a greater than operator against another roman figure")

			.WithScenario("one figure is greater than another")
				.Given(TheRomanfigure_, RomanFigure.V)
				.When(IsGreaterThan_, RomanFigure.I)
				.Then(Is_, true)

			.WithScenario("one figure is less than another")
				.Given(TheRomanfigure_, RomanFigure.I)
				.When(IsGreaterThan_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("one figure is equal to another")
				.Given(TheRomanfigure_, RomanFigure.X)
				.When(IsGreaterThan_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("one figure is compared to NULL")
				.Given(TheRomanfigure_, RomanFigure.N)
				.When(IsGreaterThan_, (RomanFigure)null)
				.Then(Is_, true)

				.WithScenario("NULL is compared to a figure")
				.Given(TheRomanfigure_, (RomanFigure)null)
				.When(IsGreaterThan_, RomanFigure.N)
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		[Test]
		public void GreaterThanOrEqualRomanFigure()
		{
			new Story("greater than or equal to roman figure")
				.InOrderTo("say that a figure is greater than or equal to another figure")
				.AsA("library user")
				.IWant("apply a greater than or equal operator against another roman figure")

			.WithScenario("one figure is greater than another")
				.Given(TheRomanfigure_, RomanFigure.V)
				.When(IsGreaterThanOrEqual_, RomanFigure.I)
				.Then(Is_, true)

			.WithScenario("one figure is less than another")
				.Given(TheRomanfigure_, RomanFigure.I)
				.When(IsGreaterThanOrEqual_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("one figure is equal to another")
				.Given(TheRomanfigure_, RomanFigure.X)
				.When(IsGreaterThanOrEqual_, RomanFigure.X)
				.Then(Is_, true)

			.WithScenario("one figure is compared to NULL")
				.Given(TheRomanfigure_, RomanFigure.N)
				.When(IsGreaterThanOrEqual_, (RomanFigure)null)
				.Then(Is_, true)

				.WithScenario("NULL is compared to a figure")
				.Given(TheRomanfigure_, (RomanFigure)null)
				.When(IsGreaterThanOrEqual_, RomanFigure.N)
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		[Test]
		public void LessThanRomanFigure()
		{
			new Story("less than roman figure")
				.InOrderTo("say that a figure is less than another figure")
				.AsA("library user")
				.IWant("apply a less than operator against another roman figure")

			.WithScenario("one figure is greater than another")
				.Given(TheRomanfigure_, RomanFigure.V)
				.When(IsLessThan_, RomanFigure.I)
				.Then(Is_, false)

			.WithScenario("one figure is less than another")
				.Given(TheRomanfigure_, RomanFigure.I)
				.When(IsLessThan_, RomanFigure.X)
				.Then(Is_, true)

			.WithScenario("one figure is equal to another")
				.Given(TheRomanfigure_, RomanFigure.X)
				.When(IsLessThan_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("one figure is compared to NULL")
				.Given(TheRomanfigure_, RomanFigure.N)
				.When(IsLessThan_, (RomanFigure)null)
				.Then(Is_, false)

				.WithScenario("NULL is compared to a figure")
				.Given(TheRomanfigure_, (RomanFigure)null)
				.When(IsLessThan_, RomanFigure.N)
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		[Test]
		public void LessThanOrEqualToRomanFigure()
		{
			new Story("less than or equal to roman figure")
				.InOrderTo("say that a figure is less than or equal to another figure")
				.AsA("library user")
				.IWant("apply a less than or equal operator against another roman figure")

			.WithScenario("one figure is greater than another")
				.Given(TheRomanfigure_, RomanFigure.V)
				.When(IsLessThanOrEqual_, RomanFigure.I)
				.Then(Is_, false)

			.WithScenario("one figure is less than another")
				.Given(TheRomanfigure_, RomanFigure.I)
				.When(IsLessThanOrEqual_, RomanFigure.X)
				.Then(Is_, true)

			.WithScenario("one figure is equal to another")
				.Given(TheRomanfigure_, RomanFigure.X)
				.When(IsLessThanOrEqual_, RomanFigure.X)
				.Then(Is_, true)

			.WithScenario("one figure is compared to NULL")
				.Given(TheRomanfigure_, RomanFigure.N)
				.When(IsLessThanOrEqual_, (RomanFigure)null)
				.Then(Is_, false)

				.WithScenario("NULL is compared to a figure")
				.Given(TheRomanfigure_, (RomanFigure)null)
				.When(IsLessThanOrEqual_, RomanFigure.N)
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		private void IsZero()
		{
			Assert.That(_comparison, Is.EqualTo(0));
		}

		private void IsLessThanZero()
		{
			Assert.That(_comparison, Is.LessThan(0));
		}

		private void IsGreaterThanZero()
		{
			Assert.That(_comparison, Is.GreaterThan(0));
		}

		private int _comparison;

		private void IsComparedTo_(RomanFigure anotherFigure)
		{
			_comparison = _subject.CompareTo(anotherFigure);
		}

		RomanFigure _subject;
		private void TheRomanfigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		private void IsGreaterThan_(RomanFigure right)
		{
			operate(left => left > right);
		}

		private void IsLessThan_(RomanFigure right)
		{
			operate(left => left < right);
		}

		private void IsGreaterThanOrEqual_(RomanFigure right)
		{
			operate(left => left >= right);
		}

		private void IsLessThanOrEqual_(RomanFigure right)
		{
			operate(left => left <= right);
		}

		bool _operation;
		private void operate(Func<RomanFigure, bool> operation)
		{
			_operation = operation(_subject);
		}

		private void Is_(bool value)
		{
			Assert.That(_operation, Is.EqualTo(value));
		}
	}

	[TestFixture]
	public class NumberComparisonTester
	{
		[Test]
		public void CompareToNumber()
		{
			new Story("compare to number")
				.InOrderTo("say that a figure is greater or lower than a number")
				.AsA("library user")
				.IWant("compare a roman figure against a number")

			.WithScenario("one figure is greater than a number")
				.Given(TheRomanfigure_, RomanFigure.V)
				.When(IsComparedTo_, 1)
				.Then(IsGreaterThanZero)

			.WithScenario("one figure is less than a number")
				.Given(TheRomanfigure_, RomanFigure.I)
				.When(IsComparedTo_, 10)
				.Then(IsLessThanZero)

			.WithScenario("one figure is equal to a number")
				.Given(TheRomanfigure_, RomanFigure.X)
				.When(IsComparedTo_, 10)
				.Then(IsZero)

			.ExecuteWithReport();
		}

		[Test]
		public void GreaterThanNumber()
		{
			new Story("greater than number")
				.InOrderTo("say that a figure is greater than a number")
				.AsA("library user")
				.IWant("apply a greater than operator against a  number")

			.WithScenario("one figure is greater than a number")
				.Given(TheRomanfigure_, RomanFigure.V)
				.When(IsGreaterThan_, 1)
				.Then(Is_, true)

			.WithScenario("one figure is less than a number")
				.Given(TheRomanfigure_, RomanFigure.I)
				.When(IsGreaterThan_, 10)
				.Then(Is_, false)

			.WithScenario("one figure is equal to a number")
				.Given(TheRomanfigure_, RomanFigure.X)
				.When(IsGreaterThan_, 10)
				.Then(Is_, false)

			.WithScenario("NULL is compared to a number")
				.Given(TheRomanfigure_, (RomanFigure)null)
				.When(IsGreaterThan_, 0)
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		[Test]
		public void GreaterThanRomanFigure()
		{
			new Story("greater than roman figure")
				.InOrderTo("say that a number is greater than a roman figure")
				.AsA("library user")
				.IWant("apply a greater than operator against a roman figure")

			.WithScenario("one number is greater than a figure")
				.Given(TheNumber_, 5)
				.When(IsGreaterThan_, RomanFigure.I)
				.Then(Is_, true)

			.WithScenario("one number is less than a figure")
				.Given(TheNumber_, 1)
				.When(IsGreaterThan_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("one number is equal to a number")
				.Given(TheNumber_, 10)
				.When(IsGreaterThan_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("one number is compared to NULL")
				.Given(TheNumber_, 0)
				.When(IsGreaterThan_, (RomanFigure)null)
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		[Test]
		public void GreaterThanOrEqualToNumber()
		{
			new Story("greater than or equal to number")
				.InOrderTo("say that a figure is greater than or equal to a number")
				.AsA("library user")
				.IWant("apply a greater than or equal operator against a number")

			.WithScenario("one figure is greater than a number")
				.Given(TheRomanfigure_, RomanFigure.V)
				.When(IsGreaterThanOrEqual_, 1)
				.Then(Is_, true)

			.WithScenario("one figure is less than a number")
				.Given(TheRomanfigure_, RomanFigure.I)
				.When(IsGreaterThanOrEqual_, 10)
				.Then(Is_, false)

			.WithScenario("one figure is equal to a number")
				.Given(TheRomanfigure_, RomanFigure.X)
				.When(IsGreaterThanOrEqual_, 10)
				.Then(Is_, true)

			.WithScenario("NULL is compared to a a number")
				.Given(TheRomanfigure_, (RomanFigure)null)
				.When(IsGreaterThanOrEqual_, 0)
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		[Test]
		public void GreaterThanOrEqualRomanFigure()
		{
			new Story("greater than or equal to roman figure")
				.InOrderTo("say that a figure is greater than or equal to another figure")
				.AsA("library user")
				.IWant("apply a greater than or equal operator against another roman figure")

			.WithScenario("one numer is greater than a figure")
				.Given(TheNumber_, 5)
				.When(IsGreaterThanOrEqual_, RomanFigure.I)
				.Then(Is_, true)

			.WithScenario("one number is less than a figure")
				.Given(TheNumber_, 1)
				.When(IsGreaterThanOrEqual_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("one number is equal to a figure")
				.Given(TheNumber_, 10)
				.When(IsGreaterThanOrEqual_, RomanFigure.X)
				.Then(Is_, true)

			.WithScenario("one number is compared to NULL")
				.Given(TheNumber_, 0)
				.When(IsGreaterThanOrEqual_, (RomanFigure)null)
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		[Test]
		public void LessThanNumber()
		{
			new Story("less than number")
				.InOrderTo("say that a figure is less than a number")
				.AsA("library user")
				.IWant("apply a less than operator against a number")

			.WithScenario("one figure is greater than a number")
				.Given(TheRomanfigure_, RomanFigure.V)
				.When(IsLessThan_, 1)
				.Then(Is_, false)

			.WithScenario("one figure is less than a number")
				.Given(TheRomanfigure_, RomanFigure.I)
				.When(IsLessThan_, 10)
				.Then(Is_, true)

			.WithScenario("one figure is equal to a number")
				.Given(TheRomanfigure_, RomanFigure.X)
				.When(IsLessThan_, 10)
				.Then(Is_, false)

			.WithScenario("NULL is compared to a number")
				.Given(TheRomanfigure_, (RomanFigure)null)
				.When(IsLessThan_, 0)
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		[Test]
		public void LessThanRomanFigure()
		{
			new Story("less than roman figure")
				.InOrderTo("say that a number is less than a number")
				.AsA("library user")
				.IWant("apply a less than operator against a roman figure")

				.WithScenario("one number is greater than a figure")
				.Given(TheNumber_, 5)
				.When(IsLessThan_, RomanFigure.I)
				.Then(Is_, false)

				.WithScenario("one number is less than a number")
				.Given(TheNumber_, 1)
				.When(IsLessThan_, RomanFigure.X)
				.Then(Is_, true)

				.WithScenario("one number is equal to a number")
				.Given(TheNumber_, 10)
				.When(IsLessThan_, RomanFigure.X)
				.Then(Is_, false)

				.WithScenario("one number is compared to NULL")
				.Given(TheNumber_, 0)
				.When(IsLessThan_, (RomanFigure)null)
				.Then(Is_, false)

				.ExecuteWithReport();
		}

		[Test]
		public void LessThanOrEqualToNumber()
		{
			new Story("less than or equal to number")
				.InOrderTo("say that a figure is less than or equal to a number")
				.AsA("library user")
				.IWant("apply a less than or equal operator against a number")

			.WithScenario("one figure is greater than a number")
				.Given(TheRomanfigure_, RomanFigure.V)
				.When(IsLessThanOrEqual_, 1)
				.Then(Is_, false)

			.WithScenario("one figure is less than a number")
				.Given(TheRomanfigure_, RomanFigure.I)
				.When(IsLessThanOrEqual_, 10)
				.Then(Is_, true)

			.WithScenario("one figure is equal to a number")
				.Given(TheRomanfigure_, RomanFigure.X)
				.When(IsLessThanOrEqual_, 10)
				.Then(Is_, true)

			.WithScenario("NULL is compared to a figure")
				.Given(TheRomanfigure_, (RomanFigure)null)
				.When(IsLessThanOrEqual_, 0)
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		[Test]
		public void LessThanOrEqualToRomanFigure()
		{
			new Story("less than or equal to roman figure")
				.InOrderTo("say that a number is less than or equal to a roman figure")
				.AsA("library user")
				.IWant("apply a less than or equal operator against a roman figure")

				.WithScenario("one number is greater than a figure")
				.Given(TheNumber_, 5)
				.When(IsLessThanOrEqual_, RomanFigure.I)
				.Then(Is_, false)

				.WithScenario("one number is less than a figure")
				.Given(TheNumber_, 1)
				.When(IsLessThanOrEqual_, RomanFigure.X)
				.Then(Is_, true)

				.WithScenario("one number is equal to a figure")
				.Given(TheNumber_, 10)
				.When(IsLessThanOrEqual_, RomanFigure.X)
				.Then(Is_, true)

				.WithScenario("one number is compared to NULL")
				.Given(TheNumber_, 0)
				.When(IsLessThanOrEqual_, (RomanFigure)null)
				.Then(Is_, false)


				.ExecuteWithReport();
		}

		private void IsZero()
		{
			Assert.That(_comparison, Is.EqualTo(0));
		}

		private void IsLessThanZero()
		{
			Assert.That(_comparison, Is.LessThan(0));
		}

		private void IsGreaterThanZero()
		{
			Assert.That(_comparison, Is.GreaterThan(0));
		}

		private int _comparison;

		private void IsComparedTo_(int number)
		{
			_comparison = _subject.CompareTo((short)number);
		}

		RomanFigure _subject;
		private void TheRomanfigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		short _number;
		private void TheNumber_(int number)
		{
			_number = (short)number;
		}

		private void IsGreaterThan_(int right)
		{
			operate(left => left > (short)right);
		}

		private void IsGreaterThan_(RomanFigure right)
		{
			operateWithNumber(left => left > right);
		}

		private void IsLessThan_(int right)
		{
			operate(left => left < (short)right);
		}

		private void IsLessThan_(RomanFigure right)
		{
			operateWithNumber(left => left < right);
		}

		private void IsGreaterThanOrEqual_(int right)
		{
			operate(left => left >= (short)right);
		}

		private void IsGreaterThanOrEqual_(RomanFigure right)
		{
			operateWithNumber(left => left >= right);
		}

		private void IsLessThanOrEqual_(int right)
		{
			operate(left => left <= (short)right);
		}

		private void IsLessThanOrEqual_(RomanFigure right)
		{
			operateWithNumber(left => left <= right);
		}

		bool _operation;
		private void operate(Func<RomanFigure, bool> operation)
		{
			_operation = operation(_subject);
		}

		private void operateWithNumber(Func<short, bool> operation)
		{
			_operation = operation(_number);
		}

		private void Is_(bool value)
		{
			Assert.That(_operation, Is.EqualTo(value));
		}
	}

	[TestFixture]
	public class ConvertibleTester
	{
		[Test]
		public void ConvertToBoolean()
		{
			new Story("convert to Boolean")
				.InOrderTo("convert a roman figure to boolean whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToBoolean)
				.Then(Is_, false)

			.WithScenario("one")
				.Given(TheRomanFigure_, RomanFigure.I)
				.When(ConvertedToBoolean)
				.Then(Is_, true)

			.WithScenario("more than one")
				.Given(TheRomanFigure_, RomanFigure.D)
				.When(ConvertedToBoolean)
				.Then(Is_, true)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToBoolean)
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToChar()
		{
			new Story("convert to Char")
				.InOrderTo("convert a roman figure to a char whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToChar)
				.Then(Is_, 'N')

			.WithScenario("more than one")
				.Given(TheRomanFigure_, RomanFigure.D)
				.When(ConvertedToChar)
				.Then(Is_, 'D')

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToChar)
				.Then(Is_, 'M')

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToSByte()
		{
			new Story("convert to SByte")
				.InOrderTo("convert a roman figure to a signed byte whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToSByte)
				.Then(Is_, 0)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToSByte)
				.Then(Is_, 100)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToSByte)
				.Then(Overflows)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToByte()
		{
			new Story("convert to Byte")
				.InOrderTo("convert a roman figure to a byte whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToByte)
				.Then(Is_, 0)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToByte)
				.Then(Is_, 100)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToByte)
				.Then(Overflows)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToShort()
		{
			new Story("convert to short")
				.InOrderTo("convert a roman figure to a short whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToShort)
				.Then(Is_, 0)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToShort)
				.Then(Is_, 100)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToShort)
				.Then(Is_, 1000)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToUShort()
		{
			new Story("convert to UShort")
				.InOrderTo("convert a roman figure to an unsigned short whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToUShort)
				.Then(Is_, 0)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToUShort)
				.Then(Is_, 100)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToUShort)
				.Then(Is_, 1000)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToInt()
		{
			new Story("convert to Int")
				.InOrderTo("convert a roman figure to an int whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToInt)
				.Then(Is_, 0)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToInt)
				.Then(Is_, 100)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToInt)
				.Then(Is_, 1000)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToUInt()
		{
			new Story("convert to UInt")
				.InOrderTo("convert a roman figure to an unsigned int whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToUInt)
				.Then(Is_, 0)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToUInt)
				.Then(Is_, 100)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToUInt)
				.Then(Is_, 1000)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToLong()
		{
			new Story("convert to Long")
				.InOrderTo("convert a roman figure to a long whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToLong)
				.Then(Is_, 0)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToLong)
				.Then(Is_, 100)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToLong)
				.Then(Is_, 1000)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToULong()
		{
			new Story("convert to ULong")
				.InOrderTo("convert a roman figure to an unsigned long whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToULong)
				.Then(Is_, 0)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToULong)
				.Then(Is_, 100)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToULong)
				.Then(Is_, 1000)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToFloat()
		{
			new Story("convert to Float")
				.InOrderTo("convert a roman figure to a float whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToFloat)
				.Then(Is_, 0)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToFloat)
				.Then(Is_, 100)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToFloat)
				.Then(Is_, 1000)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToDouble()
		{
			new Story("convert to Double")
				.InOrderTo("convert a roman figure to a double whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToDouble)
				.Then(Is_, 0)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToDouble)
				.Then(Is_, 100)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToDouble)
				.Then(Is_, 1000)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToDecimal()
		{
			new Story("convert to Decimal")
				.InOrderTo("convert a roman figure to a decimal whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToDecimal)
				.Then(Is_, 0)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToDecimal)
				.Then(Is_, 100)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToDecimal)
				.Then(Is_, 1000)

			.ExecuteWithReport();
		}

		[Test]
		public void ConvertToDateTime()
		{
			new Story("convert to DateTime")
				.InOrderTo("convert a roman figure to date-time whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("zero")
				.Given(TheRomanFigure_, RomanFigure.N)
				.When(ConvertedToDateTime)
				.Then(CannotCast)

			.WithScenario("less than max")
				.Given(TheRomanFigure_, RomanFigure.C)
				.When(ConvertedToDateTime)
				.Then(CannotCast)

			.WithScenario("max")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedToDateTime)
				.Then(CannotCast)

			.ExecuteWithReport();
		}

		[Test]
		public void ChangeType()
		{
			new Story("ChangeType")
				.InOrderTo("convert a roman figure to a clr type whenever possible")
				.AsA("library user")
				.IWant("Convert() to a roman figure")

			.WithScenario("supported type")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedTo_, typeof(long))
				.Then(Is_, 1000)

			.WithScenario("overflowing type")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedTo_, typeof(byte))
				.Then(Overflows)

			.WithScenario("unsupported type")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedTo_, typeof(TimeSpan))
				.Then(CannotCast)

			.WithScenario("unsupported type")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedTo_, typeof(Exception))
				.Then(CannotCast)

			.WithScenario("itself")
				.Given(TheRomanFigure_, RomanFigure.M)
				.When(ConvertedTo_, typeof(RomanFigure))
				.Then(Is_, RomanFigure.M)

			.ExecuteWithReport();
		}

		Func<object> _conversion;
		private void ConvertedToBoolean()
		{
			_conversion = () => Convert.ToBoolean(_subject);
		}

		private void ConvertedToChar()
		{
			_conversion = () => Convert.ToChar(_subject);
		}

		private void ConvertedToSByte()
		{
			_conversion = () => Convert.ToSByte(_subject);
		}

		private void ConvertedToByte()
		{
			_conversion = () => Convert.ToByte(_subject);
		}

		private void ConvertedToShort()
		{
			_conversion = () => Convert.ToInt16(_subject);
		}

		private void ConvertedToUShort()
		{
			_conversion = () => Convert.ToUInt16(_subject);
		}

		private void ConvertedToInt()
		{
			_conversion = () => Convert.ToInt32(_subject);
		}

		private void ConvertedToUInt()
		{
			_conversion = () => Convert.ToUInt32(_subject);
		}

		private void ConvertedToLong()
		{
			_conversion = () => Convert.ToInt64(_subject);
		}

		private void ConvertedToULong()
		{
			_conversion = () => Convert.ToUInt64(_subject);
		}

		private void ConvertedToFloat()
		{
			_conversion = () => Convert.ToSingle(_subject);
		}

		private void ConvertedToDouble()
		{
			_conversion = () => Convert.ToDouble(_subject);
		}

		private void ConvertedToDecimal()
		{
			_conversion = () => Convert.ToDecimal(_subject);
		}

		private void ConvertedToDateTime()
		{
			_conversion = () => Convert.ToDateTime(_subject);
		}

		private void ConvertedTo_(Type to)
		{
			_conversion = () => Convert.ChangeType(_subject, to);
		}

		RomanFigure _subject;
		private void TheRomanFigure_(RomanFigure subject)
		{
			_subject = subject;
		}

		private void Is_(bool value)
		{
			Assert.That(_conversion(), Is.EqualTo(value));
		}

		private void Is_(char value)
		{
			Assert.That(_conversion(), Is.EqualTo(value));
		}

		private void Is_(int value)
		{
			Assert.That(_conversion(), Is.EqualTo(value));
		}

		private void Is_(RomanFigure value)
		{
			Assert.That(_conversion(), Is.EqualTo(value));
		}

		private void Overflows()
		{
			TestDelegate conversion = () => _conversion();
			Assert.That(conversion, Throws.InstanceOf<OverflowException>());
		}

		private void CannotCast()
		{
			TestDelegate conversion = () => _conversion();
			Assert.That(conversion, Throws.InstanceOf<InvalidCastException>()
				.With.Message.StringContaining(typeof(RomanFigure).Name));
		}
	}

	[TestFixture]
	public class EquatableTester
	{
		private bool _operation;
		private RomanFigure _subject;

		[Test]
		public void Equatable()
		{
			new Story("non generic equatable")
				.InOrderTo("say that an object is equal to a roman figure")
				.AsA("library user")
				.IWant("to use .Equals() against an object")

			.WithScenario("a roman figure is compared against a boxed char with the same value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, (object)'V')
				.Then(Is_, true)

			.WithScenario("a roman figure is compared against a boxed char with a different value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, (object)'X')
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against a boxed short with the same value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, (object)((short)5))
				.Then(Is_, true)

			.WithScenario("a roman figure is compared against a boxed short with a different value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, (object)((short)10))
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against the same objtified figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, (object)RomanFigure.V)
				.Then(Is_, true)

			.WithScenario("a roman figure is compared against another objtified figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, (object)RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against null")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, (object)null)
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against a boxed lowercase char with the same value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, (object)'v')
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against a boxed int with the same value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, (object)5)
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void ComparedTo_(object o)
		{
			_operation = _subject.Equals(o);
		}

		private void TheRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}
	}

	[TestFixture]
	public class EquatableToRomanFigureTester
	{
		private bool _operation;
		private IEquatable<RomanFigure> _subject;

		[Test]
		public void EquatableToRomanFigure()
		{
			new Story("equatable to roman figure")
				.InOrderTo("say that a figure is equal to another figure")
				.AsA("library user")
				.IWant("to use IEquatable<RomanFigure> methods against a roman figure")

			.WithScenario("a roman figure is compared against the same roman figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, RomanFigure.V)
				.Then(Is_, true)

			.WithScenario("a roman figure is compared against not the same roman figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against null")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, (RomanFigure)null)
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void ComparedTo_(RomanFigure anotherFigure)
		{
			_operation = _subject.Equals(anotherFigure);
		}

		private void TheRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}
	}

	[TestFixture]
	public class EquatableToShortFigureTester
	{
		private bool _operation;
		private IEquatable<short> _subject;

		[Test]
		public void EquatableToToShort()
		{
			new Story("equatable to a number")
				.InOrderTo("say that a figure is equal to a number")
				.AsA("library user")
				.IWant("to use IEquatable<short> methods against a roman figure")

			.WithScenario("a roman figure is compared against a number with the same value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, 5)
				.Then(Is_, true)

			.WithScenario("a roman figure is compared against a number with a different value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, 10)
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void ComparedTo_(int number)
		{
			_operation = _subject.Equals((short)number);
		}

		private void TheRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

	}

	[TestFixture]
	public class EquatableToCharFigureTester
	{
		private bool _operation;
		private IEquatable<char> _subject;

		[Test]
		public void EquatableToChar()
		{
			new Story("equatable to a char")
				.InOrderTo("say that a figure is equal to a char")
				.AsA("library user")
				.IWant("to use IEquatable<char> methods against a roman figure")

			.WithScenario("a roman figure is compared against a char with the same value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, 'V')
				.Then(Is_, true)

			.WithScenario("a roman figure is compared against a char with a different value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, 'X')
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against a char with the same value and different case")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(ComparedTo_, 'v')
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void ComparedTo_(char charFigure)
		{
			_operation = _subject.Equals(charFigure);
		}

		private void TheRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

	}

	[TestFixture]
	public class RomanFigureEqualityOperatorTester
	{
		private bool _operation;
		private RomanFigure _subject;

		[Test]
		public void EqualsToRomanFigure()
		{
			new Story("equality to roman figure")
				.InOrderTo("say that a figure is equal to another figure")
				.AsA("library user")
				.IWant("to use the equality operator against a roman figure")

			.WithScenario("a roman figure is compared against the same roman figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(EqualTo_, RomanFigure.V)
				.Then(Is_, true)

			.WithScenario("a roman figure is compared against not the same roman figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(EqualTo_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against null")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(EqualTo_, (RomanFigure)null)
				.Then(Is_, false)

			.WithScenario("null is compared against a roman figure")
				.Given(TheRomanFigure_, (RomanFigure)null)
				.When(EqualTo_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("null is compared against null")
				.Given(TheRomanFigure_, (RomanFigure)null)
				.When(EqualTo_, (RomanFigure)null)
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void TheRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		private void EqualTo_(RomanFigure anotherFigure)
		{
			_operation = _subject == anotherFigure;
		}
	}

	[TestFixture]
	public class RomanFigureInequalityOperatorTester
	{
		private bool _operation;
		private RomanFigure _subject;

		[Test]
		public void NotEqualToRomanFigure()
		{
			new Story("inequality to roman figure")
				.InOrderTo("say that a figure is not equal to another figure")
				.AsA("library user")
				.IWant("to use the inequality operator against a roman figure")

			.WithScenario("a roman figure is compared against the same roman figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(NotEqualTo_, RomanFigure.V)
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against not the same roman figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(NotEqualTo_, RomanFigure.X)
				.Then(Is_, true)

			.WithScenario("a roman figure is compared against null")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(NotEqualTo_, (RomanFigure)null)
				.Then(Is_, true)

			.WithScenario("null is compared against a roman figure")
				.Given(TheRomanFigure_, (RomanFigure)null)
				.When(NotEqualTo_, RomanFigure.X)
				.Then(Is_, true)

			.WithScenario("null is compared against null")
				.Given(TheRomanFigure_, (RomanFigure)null)
				.When(NotEqualTo_, (RomanFigure)null)
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void TheRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		private void NotEqualTo_(RomanFigure anotherFigure)
		{
			_operation = _subject != anotherFigure;
		}
	}

	[TestFixture]
	public class ShortEqualityOperatorTester
	{
		private bool _operation;
		private short _subject;

		[Test]
		public void EqualsToShort()
		{
			new Story("equality to number")
				.InOrderTo("say that a short figure is equal to the value of a roman figure")
				.AsA("library user")
				.IWant("to use the equality operator against a roman figure")

				.WithScenario("a short figure is compared against the same value of a roman figure")
				.Given(TheRomanFigure_, 5u)
				.When(EqualTo_, RomanFigure.V)
				.Then(Is_, true)

				.WithScenario("a short figure is compared against not the same value of a roman figure")
				.Given(TheRomanFigure_, 5u)
				.When(EqualTo_, RomanFigure.X)
				.Then(Is_, false)

				.WithScenario("a short figure is compared against null")
				.Given(TheRomanFigure_, 5u)
				.When(EqualTo_, (RomanFigure)null)
				.Then(Is_, false)

				.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void TheRomanFigure_(uint value)
		{
			_subject = (short)value;
		}

		private void EqualTo_(RomanFigure figure)
		{
			_operation = _subject == figure;
		}
	}

	[TestFixture]
	public class ShortInequalityOperatorTester
	{
		private bool _operation;
		private RomanFigure _subject;

		[Test]
		public void NotEqualToShort()
		{
			new Story("inequality to number")
				.InOrderTo("say that a figure is not equal to a short figure")
				.AsA("library user")
				.IWant("to use the inequality operator against a short figure")

			.WithScenario("a roman figure is compared against a short figure with the same value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(NotEqualTo_, 5u)
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against a short figure not the same value")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(NotEqualTo_, 10u)
				.Then(Is_, true)

			.WithScenario("null is compared against a short value")
				.Given(TheRomanFigure_, (RomanFigure)null)
				.When(NotEqualTo_, 10u)
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void TheRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		private void NotEqualTo_(uint value)
		{
			_operation = _subject != (short)value;
		}
	}

	[TestFixture]
	public class InverseShortFigureEqualityOperatorTester
	{
		private bool _operation;
		private short _subject;

		[Test]
		public void EqualToNumber()
		{
			new Story("equality to number")
				.InOrderTo("say that a number is equal to a roman figure")
				.AsA("library user")
				.IWant("to use the equality operator against a roman figure")

			.WithScenario("a short figure is compared against the same value of a roman figure")
				.Given(TheRomanFigure_, 5u)
				.When(EqualTo_, RomanFigure.V)
				.Then(Is_, true)

			.WithScenario("a short figure is compared against not the same value of a roman figure")
				.Given(TheRomanFigure_, 5u)
				.When(EqualTo_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("a short figure is compared against null")
				.Given(TheRomanFigure_, 5u)
				.When(EqualTo_, (RomanFigure)null)
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void TheRomanFigure_(uint value)
		{
			_subject = (short)value;
		}

		private void EqualTo_(RomanFigure figure)
		{
			_operation = _subject == figure;
		}
	}

	[TestFixture]
	public class InverseShortFigureInequalityOperatorTester
	{
		private bool _operation;
		private short _subject;

		[Test]
		public void NotEqualToNumber()
		{
			new Story("inequality to number")
				.InOrderTo("say that a number is not equal to a roman figure")
				.AsA("library user")
				.IWant("to use the inequality operator against a roman figure")

			.WithScenario("a short figure is compared against the same value of a roman figure")
				.Given(TheRomanFigure_, 5u)
				.When(NotEqualTo_, RomanFigure.V)
				.Then(Is_, false)

			.WithScenario("a short figure is compared against not the same value of a roman figure")
				.Given(TheRomanFigure_, 5u)
				.When(NotEqualTo_, RomanFigure.X)
				.Then(Is_, true)

			.WithScenario("a short figure is compared against null")
				.Given(TheRomanFigure_, 5u)
				.When(NotEqualTo_, (RomanFigure)null)
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void TheRomanFigure_(uint value)
		{
			_subject = (short)value;
		}

		private void NotEqualTo_(RomanFigure figure)
		{
			_operation = _subject != figure;
		}
	}

	[TestFixture]
	public class CharEqualityOperatorTester
	{
		private bool _operation;
		private RomanFigure _subject;

		[Test]
		public void EqualsToChar()
		{
			new Story("equality to char")
				.InOrderTo("say that a figure is equal to a char figure")
				.AsA("library user")
				.IWant("to use the equality operator against a char figure")

			.WithScenario("a roman figure is compared against the same figure as a char figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(EqualTo_, 'V')
				.Then(Is_, true)

			.WithScenario("a roman figure is compared against not the same figure as a char figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(EqualTo_, 'X')
				.Then(Is_, false) 

			.WithScenario("null is compared against a char figure")
				.Given(TheRomanFigure_, (RomanFigure)null)
				.When(EqualTo_, 'X')
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against the same figure as a lowercase char figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(EqualTo_, 'v')
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void TheRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		private void EqualTo_(char character)
		{
			_operation = _subject == character;
		}
	}

	[TestFixture]
	public class CharInequalityOperatorTester
	{
		private bool _operation;
		private RomanFigure _subject;

		[Test]
		public void NotEqualToChar()
		{
			new Story("inequality to char")
				.InOrderTo("say that a figure is not equal to a char figure")
				.AsA("library user")
				.IWant("to use the inequality operator against a char figure")

			.WithScenario("a roman figure is compared against the same figure as a char figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(NotEqualTo_, 'V')
				.Then(Is_, false)

			.WithScenario("a roman figure is compared against not the same roman figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(NotEqualTo_, 'X')
				.Then(Is_, true)

			.WithScenario("null is compared against a roman figure")
				.Given(TheRomanFigure_, (RomanFigure)null)
				.When(NotEqualTo_, 'X')
				.Then(Is_, true)

			.WithScenario("a roman figure is compared against the same figure as a lowercase char figure")
				.Given(TheRomanFigure_, RomanFigure.V)
				.When(NotEqualTo_, 'v')
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void TheRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		private void NotEqualTo_(char figure)
		{
			_operation = _subject != figure;
		}
	}

	[TestFixture]
	public class InverseCharEqualityOperatorTester
	{
		private bool _operation;
		private char _subject;

		[Test]
		public void EqualsToRomanFigure()
		{
			new Story("equality to char")
				.InOrderTo("say that a char is equal to a roman figure")
				.AsA("library user")
				.IWant("to use the equality operator against a roman figure")

			.WithScenario("a char figure is compared against a roman figure with the same figure")
				.Given(TheRomanFigure_, 'V')
				.When(EqualTo_, RomanFigure.V)
				.Then(Is_, true)

			.WithScenario("a roman figure is compared against a roman figure not with the same figure")
				.Given(TheRomanFigure_, 'V')
				.When(EqualTo_, RomanFigure.X)
				.Then(Is_, false)

			.WithScenario("a char figure is compared against null")
				.Given(TheRomanFigure_, 'V')
				.When(EqualTo_, (RomanFigure)null)
				.Then(Is_, false)

			.WithScenario("a lowercase char figure is compared against a roman figure with the same figure")
				.Given(TheRomanFigure_, 'v')
				.When(EqualTo_, RomanFigure.V)
				.Then(Is_, false)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void TheRomanFigure_(char character)
		{
			_subject = character;
		}

		private void EqualTo_(RomanFigure figure)
		{
			_operation = _subject == figure;
		}
	}

	[TestFixture]
	public class InverseCharInequalityOperatorTester
	{
		private bool _operation;
		private char _subject;

		[Test]
		public void NotEqualToChar()
		{
			new Story("inequality to char")
				.InOrderTo("say that a char figure is not equal to a roman figure")
				.AsA("library user")
				.IWant("to use the inequality operator against a roman figure")

			.WithScenario("a char figure is compared against a roman figure with the same figure")
				.Given(TheRomanFigure_, 'V')
				.When(NotEqualTo_, RomanFigure.V)
				.Then(Is_, false)

			.WithScenario("a char figure is compared against a roman figure not with the same figure")
				.Given(TheRomanFigure_, 'V')
				.When(NotEqualTo_, RomanFigure.X)
				.Then(Is_, true)

			.WithScenario("a char figure is compared against null")
				.Given(TheRomanFigure_, 'V')
				.When(NotEqualTo_, (RomanFigure)null)
				.Then(Is_, true)

			.WithScenario("a lowercase char figure is compared against a roman figure with the same figure")
				.Given(TheRomanFigure_, 'v')
				.When(NotEqualTo_, RomanFigure.V)
				.Then(Is_, true)

			.ExecuteWithReport();
		}

		private void Is_(bool result)
		{
			Assert.That(_operation, Is.EqualTo(result));
		}

		private void TheRomanFigure_(char character)
		{
			_subject = character;
		}

		private void NotEqualTo_(RomanFigure figure)
		{
			_operation = _subject != figure;
		}
	}

	[TestFixture]
	public class ConversionToCharTester
	{
		[Test]
		public void CastToChar()
		{
			new Story("conversion to char")
				.InOrderTo("get the character of individual figures")
				.AsA("library user")
				.IWant("to be able to cast a roman figure")

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.N)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'N')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.I)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'I')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.V)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'V')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.X)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'X')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.L)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'L')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.C)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'C')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.D)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'D')

				.WithScenario("character of a figure")
					.Given(aRomanFigure_, RomanFigure.M)
					.When(theCharacterIsObtained)
					.Then(theCharacter_Is, 'M')

				.WithScenario("character of null")
					.Given(aRomanFigure_, (RomanFigure)null)
					.When(theCharacterIsObtained)
					.Then(throwsArgumentException)

				.ExecuteWithReport();
		}

		private void throwsArgumentException()
		{
			TestDelegate cast = () => _character();
			Assert.That(cast, Throws.InstanceOf<ArgumentNullException>());
		}

		RomanFigure _subject;
		private void aRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		Func<char> _character;
		private void theCharacterIsObtained()
		{
			_character = () => (char)_subject;
		}

		private void theCharacter_Is(char character)
		{
			Assert.That(_character(), Is.EqualTo(character));
		}
	}

	[TestFixture]
	public class ConversionFromCharTester
	{
		[Test]
		public void CastToChar()
		{
			new Story("conversion from char")
				.InOrderTo("get the figure from a character")
				.AsA("library user")
				.IWant("to be able to cast a character")

				.WithScenario("figure of a defined character")
					.Given(aCharacter_, 'N')
					.When(theFigureIsObtained)
					.Then(theFigure_Is, RomanFigure.N)

				.WithScenario("figure of a defined character")
					.Given(aCharacter_, 'I')
					.When(theFigureIsObtained)
					.Then(theFigure_Is, RomanFigure.I)

				.WithScenario("figure of a defined character")
					.Given(aCharacter_, 'V')
					.When(theFigureIsObtained)
					.Then(theFigure_Is, RomanFigure.V)

				.WithScenario("figure of a defined character")
					.Given(aCharacter_, 'X')
					.When(theFigureIsObtained)
					.Then(theFigure_Is, RomanFigure.X)

				.WithScenario("figure of a defined character")
					.Given(aCharacter_, 'L')
					.When(theFigureIsObtained)
					.Then(theFigure_Is, RomanFigure.L)

				.WithScenario("figure of a defined character")
					.Given(aCharacter_, 'C')
					.When(theFigureIsObtained)
					.Then(theFigure_Is, RomanFigure.C)

				.WithScenario("figure of a defined character")
					.Given(aCharacter_, 'D')
					.When(theFigureIsObtained)
					.Then(theFigure_Is, RomanFigure.D)

				.WithScenario("figure of a defined character")
					.Given(aCharacter_, 'M')
					.When(theFigureIsObtained)
					.Then(theFigure_Is, RomanFigure.M)

				.WithScenario("figure of an undefined character")
					.Given(aCharacter_, 'W')
					.When(theFigureIsObtained)
					.Then(throwsArgumentException)

				.WithScenario("figures are unique")
					.Given(aCharacter_, 'X')
					.When(theFigureIsObtainedFor_, 'X')
					.Then(isTheSameFigure)

				.ExecuteWithReport();
		}

		private void isTheSameFigure()
		{
			Assert.That(_figure(), Is.SameAs(_anotherFigure));
		}

		private RomanFigure _anotherFigure;
		private void theFigureIsObtainedFor_(char character)
		{
			_anotherFigure = (RomanFigure)character;
		}

		private void throwsArgumentException()
		{
			TestDelegate cast = () => _figure();
			Assert.That(cast, Throws.ArgumentException);
		}

		char _subject;
		private void aCharacter_(char character)
		{
			_subject = character;
		}

		Func<RomanFigure> _figure;
		private void theFigureIsObtained()
		{
			_figure = () => (RomanFigure)_subject;
		}

		private void theFigure_Is(RomanFigure figure)
		{
			Assert.That(_figure(), Is.EqualTo(figure));
		}
	}

	[TestFixture]
	public class ConversionToShortTester
	{
		[Test]
		public void CastToShort()
		{
			new Story("conversion to short")
				.InOrderTo("convert roman figure to short value")
				.AsA("library user")
				.IWant("to be able to cast to a short")

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.N)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 0u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.I)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 1u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.V)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 5u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.X)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 10u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.L)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 50u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.C)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 100u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.D)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 500u)

				.WithScenario("value of a figure")
					.Given(aRomanFigure_, RomanFigure.M)
					.When(theValueIsObtained)
					.Then(theValue_IsCorrect, 1000u)

				.WithScenario("value of null")
					.Given(aRomanFigure_, (RomanFigure)null)
					.When(theValueIsObtained)
					.Then(throwsArgumentException)

				.ExecuteWithReport();
		}

		private void throwsArgumentException()
		{
			TestDelegate cast = () => _value();
			Assert.That(cast, Throws.InstanceOf<ArgumentNullException>());
		}

		RomanFigure _subject;
		private void aRomanFigure_(RomanFigure figure)
		{
			_subject = figure;
		}

		Func<short> _value;
		private void theValueIsObtained()
		{
			_value = () => (short)_subject;
		}

		private void theValue_IsCorrect(uint value)
		{
			Assert.That(_value(), Is.EqualTo(value));
		}
	}

	[TestFixture]
	public class ConversionFromShortTester
	{
		[Test]
		public void CastFromShort()
		{
			new Story("conversion from short")
				.InOrderTo("convert short value to a roman figure")
				.AsA("library user")
				.IWant("to be able to cast from a short")

				.WithScenario("value of a figure")
					.Given(aNumber_, 0)
					.When(theFigureIsObtained)
					.Then(theFigure_IsCorrect,RomanFigure.N )

				.WithScenario("value of a figure")
					.Given(aNumber_, 1)
					.When(theFigureIsObtained)
					.Then(theFigure_IsCorrect, RomanFigure.I)

				.WithScenario("value of a figure")
					.Given(aNumber_, 5)
					.When(theFigureIsObtained)
					.Then(theFigure_IsCorrect,RomanFigure.V)

				.WithScenario("value of a figure")
					.Given(aNumber_, 10)
					.When(theFigureIsObtained)
					.Then(theFigure_IsCorrect, RomanFigure.X)

				.WithScenario("value of a figure")
					.Given(aNumber_, 50)
					.When(theFigureIsObtained)
					.Then(theFigure_IsCorrect,RomanFigure.L)

				.WithScenario("value of a figure")
					.Given(aNumber_, 100)
					.When(theFigureIsObtained)
					.Then(theFigure_IsCorrect, RomanFigure.C)

				.WithScenario("value of a figure")
					.Given(aNumber_, 500)
					.When(theFigureIsObtained)
					.Then(theFigure_IsCorrect, RomanFigure.D)

				.WithScenario("value of a figure")
					.Given(aNumber_, 1000)
					.When(theFigureIsObtained)
					.Then(theFigure_IsCorrect, RomanFigure.M)

				.WithScenario("undefined value")
					.Given(aNumber_, 55)
					.When(theFigureIsObtained)
					.Then(throwsArgumentException)

				.ExecuteWithReport();
		}

		private void throwsArgumentException()
		{
			TestDelegate cast = () => _value();
			Assert.That(cast, Throws.ArgumentException);
		}

		short _subject;
		private void aNumber_(int number)
		{
			_subject = (short)number;
		}

		Func<RomanFigure> _value;
		private void theFigureIsObtained()
		{
			_value = () => (RomanFigure)_subject;
		}

		private void theFigure_IsCorrect(RomanFigure figure)
		{
			Assert.That(_value(), Is.EqualTo(figure));
		}
	}
}
